package edu.ucsd.cse110;

import java.util.List;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import edu.ucsd.cse110.model.Log;
import edu.ucsd.cse110.model.Wod;

/**
 * Displays a list of benchmarks or custom tabs on the right screen of the main
 * ViewPager.
 */
public class BenchmarkActivity extends ListActivity implements OnClickListener {
	/**
	 * Displays custom list item layout.
	 */
	private class BenchmarkAdapter extends ArrayAdapter<Wod> implements
			OnClickListener, OnLongClickListener {
		private Activity mActivity;
		private List<Wod> mWods;

		/**
		 * Constructs the adapter with a list of WODs.
		 */
		public BenchmarkAdapter(Context context, int textViewResourceId,
				List<Wod> objects) {
			super(context, textViewResourceId, objects);

			mActivity = (Activity) context;
			mWods = objects;
		}

		/**
		 * Fills the list item with WOD information.
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			LayoutInflater inflater = (LayoutInflater) mActivity
					.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			View view = inflater
					.inflate(R.layout.benchmark_item, parent, false);

			// Accesses database to retrieve needed data.
			LocalDatabaseManager database = new LocalDatabaseManager(mActivity);

			// Gets a sorted list of all logs in descending order by the
			// recorded time.
			List<Log> listAllLog = database.getLog(String.format("%s = ?",
					Log.COLUMNS[2]), new String[] { Integer.toString(mWods.get(
					position).getId()) }, null, null, String.format("%s DESC",
					Log.COLUMNS[2]));

			// Gets a list of logs by the WOD ID.
			List<Log> listWodLog = database.getLogByWodId(mWods.get(position)
					.getId());
			database.close();

			// Sets the name of the WOD.
			TextView txtName = (TextView) view
					.findViewById(R.id.benchmarkitem_txt_title);
			txtName.setText(mWods.get(position).getName());

			// Sets the rating of the WOD
			RatingBar ratingWod = (RatingBar) view
					.findViewById(R.id.benchmarkitem_rating);
			ratingWod.setRating(mWods.get(position).getRating());

			// Sets the last date completed of the WOD
			TextView txtLastDate = (TextView) view
					.findViewById(R.id.benchmarkitem_txt_datefield);

			// Sets the text of personal record
			TextView txtPR = (TextView) view
					.findViewById(R.id.benchmarkitem_txt_timefield);
			if (listWodLog.size() > 0) {
				String theDate = Utility.calendarToString(listAllLog.get(0)
						.getDate(), "MM/dd/yyyy");
				txtLastDate.setText(theDate);
				switch (mWods.get(position).getPRType()) {
				case Time:
					txtPR.setText(Utility.getWodBestTime(listWodLog));
					break;
				case Rep:
					txtPR.setText(Integer.toString(Utility
							.getWodBestRep(listWodLog)));
					break;
				case Round:
					int bestRound = Utility.getWodBestRound(listWodLog);
					if (bestRound > 0) {
						txtPR.setText(String.format("%d rounds", bestRound));
					}
					break;
				default:
					txtPR.setText("Error");
					break;
				}
			} else {
				txtPR.setText("N/A");
			}

			// Sets each list item to start new BenchmarkDetailActivity.
			view.setTag(position);
			view.setOnClickListener(this);

			// ENABLES CUSTOM WOD ITEMS TO BE LONG CLICKABLE TO ERASE ENTRIES
			if (mWodType == Wod.Type.Custom) {// set a new onLongClickListener
				view.setOnLongClickListener(this);
			}

			return view;
		}

		/**
		 * Starts a new activity with detailed information of the selected WOD.
		 */
		public void onClick(View v) {
			int position = (Integer) v.getTag();
			Wod item = mWods.get(position);

			Intent i = new Intent(mActivity.getParent(),
					BenchmarkDetailActivity.class);
			i.putExtra("Position", position);
			i.putExtra("Id", item.getId());
			i.putExtra("Type", item.getType().ordinal());
			mActivity.getParent()
					.startActivityForResult(i, REQUEST_CODE_DETAIL);
		}

		/**
		 * Asks if the user wants to delete an existing custom WOD when a list
		 * item is long clicked.
		 */
		public boolean onLongClick(final View v) {
			AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(
					mContext);
			myAlertDialog.setTitle("Custom WOD");
			myAlertDialog
					.setMessage("Would you like to delete this custom WOD?");
			myAlertDialog.setPositiveButton("OK",
					new DialogInterface.OnClickListener() {
						/**
						 * Deletes the custom WOD when OK button is pressed.
						 */
						public void onClick(DialogInterface dialog, int which) {
							deleteCustomWod(mListBenchmarks.get((Integer) v
									.getTag()));
							return;
						}
					});
			myAlertDialog.setNegativeButton("No",
					new DialogInterface.OnClickListener() {
						/**
						 * Does nothing when No button is pressed.
						 */
						public void onClick(DialogInterface dialog, int which) {
							return;
						}
					});
			myAlertDialog.show();
			return false;
		}
	}

	private Bundle extras;
	private ArrayAdapter<Wod> mAdapter;
	private Context mContext;
	protected List<Wod> mListBenchmarks;
	private int REQUEST_CODE_DETAIL = 20;
	private EditText theName, theDescription;
	private RadioGroup theRadioGroup;

	private Wod.Type mWodType;

	/**
	 * Adds a custom WOD to the database and the list.
	 * 
	 * @param item
	 *            The WOD to be added.
	 */
	private void addCustomWod(Wod item) {
		LocalDatabaseManager database = new LocalDatabaseManager(this);
		long id = database.insertWod(item);
		database.close();

		item.setId((int) id);
		mAdapter.add(item);
		mAdapter.notifyDataSetChanged();
	}

	/**
	 * Deletes a custom WOD from the database and the list.
	 * 
	 * @param item
	 *            The WOD to be deleted.
	 */
	private void deleteCustomWod(Wod item) {
		LocalDatabaseManager database = new LocalDatabaseManager(this);
		database.deleteWodById(item.getId());
		database.deleteLogByWodId(item.getId());
		database.close();

		mAdapter.remove(item);
		mAdapter.notifyDataSetChanged();
	}

	/**
	 * Scrolls back to the home screen when the back button is pressed.
	 */
	@Override
	public void onBackPressed() {
		XFitTracker.mPager.setCurrentItem(1);
	}

	/**
	 * Prompts the user for new custom WOD information when the "Add custom WOD"
	 * button is clicked.
	 */
	public void onClick(View v) {
		LayoutInflater factory = LayoutInflater.from(mContext);
		View view = factory.inflate(R.layout.customwod_prompt, null);

		// Initializes alert dialog.
		AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(mContext);

		// Changes the layout of the dialog.
		myAlertDialog.setTitle("Custom WOD");
		myAlertDialog.setView(view);
		theName = (EditText) view.findViewById(R.id.custom_input_name);
		theDescription = (EditText) view
				.findViewById(R.id.custom_input_description);
		theRadioGroup = (RadioGroup) view.findViewById(R.id.radio_group);
		theRadioGroup.check(R.id.radio_time);

		// Prompts user the new custom WOD dialog.
		// myAlertDialog.setMessage("Would you like to add a custom WOD?");
		myAlertDialog.setPositiveButton("OK",
				new DialogInterface.OnClickListener() {
					/**
					 * Sets up a WOD object with the input data and adds it to
					 * the database and the list.
					 */
					public void onClick(DialogInterface dialog, int which) {
						// Gets the selected PRType.
						int selectedId = theRadioGroup
								.getCheckedRadioButtonId();
						Wod.PRType type = null;
						switch (selectedId) {
						case R.id.radio_time:
							type = Wod.PRType.Time;
							break;
						case R.id.radio_rep:
							type = Wod.PRType.Rep;
							break;
						case R.id.radio_round:
							type = Wod.PRType.Round;
							break;
						}

						// Adds a new custom WOD to database.
						Wod item = new Wod();
						item.setName(theName.getText().toString());
						item.setDescription(theDescription.getText().toString());
						item.setType(Wod.Type.Custom);
						item.setPRType(type);
						addCustomWod(item);

						return;
					}
				});
		myAlertDialog.setNegativeButton("Cancel",
				new DialogInterface.OnClickListener() {
					/**
					 * Does nothing when "Cancel" button is clicked.
					 */
					public void onClick(DialogInterface dialog, int which) {
						return;
					}
				});
		myAlertDialog.show();
	}

	/**
	 * TODO: Need documentation.
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.benchmark_tab);

		mContext = this;
		extras = getIntent().getExtras();
		mWodType = Wod.Type.values()[extras.getInt("Type")];

		// Accesses database to retrieve list of benchmarks by WOD type.
		LocalDatabaseManager database = new LocalDatabaseManager(this);

		// Populates WOD list with every WOD pre and post created
		mListBenchmarks = database.getWodByType(Wod.Type.values()[extras
				.getInt("Type")]);
		database.close();

		if (mWodType == Wod.Type.Custom) {// hopefully, this is Custom type
			Toast.makeText(this, "Tap and hold an item to delete.",
					Toast.LENGTH_LONG).show();
			// Now, we just need to display the 'ADD WOD' button.
			Button addButton = (Button) findViewById(R.id.add_cust_wod);
			addButton.setVisibility(0);// make visible....good
			addButton.setOnClickListener(this);
		}

		// Creates an adapter using the list of custom WODs.
		mAdapter = new BenchmarkAdapter(this,
				android.R.layout.simple_expandable_list_item_1, mListBenchmarks);
		setListAdapter(mAdapter);
	}
}